#include "include/ChessBoard.h"

//void ChessBoard::display() {
//	for (int i = 0; i < height; i++) {
//		for (int j = 0; j < width; j++)
//			std::wcout << Assets[(chesses.at(j).at(i).getCode())];
//		std::wcout << std::endl;
//	}
//}
//

ChessBoard::~ChessBoard() {
	for (auto &i : this->chesses)
		for (auto &j : i)
			delete j;
}

ChessBoard::ChessBoard(int m_width, int m_height, Asset blank)
	: m_width(m_width)
	, m_height(m_height) {
	this->chesses.resize(m_width);
	for (auto &i : this->chesses) {
		i.resize(m_height);
		for (auto &j : i) {
			j = new OnlySetChess(-1, BLANK);
		}
	}
	this->Assets.push_back(blank);
}

int ChessBoard::getWidth() {
	return this->m_width;
}

int ChessBoard::getHeight() {
	return this->m_height;
}

void ChessBoard::loadAsset(Asset asset) {
	this->Assets.push_back(asset);
}

BasicChess *ChessBoard::getChess(const Position &pos) {
	return this->chesses.at(pos.x).at(pos.y);
}

//bool ChessBoard::set(int who, const Position &pos) {
//	OnlySetChess *dst = (OnlySetChess*)this->getChess(pos);
//
//	if (dst->getOwner() == -1) {
//		dst->setOwner(who);
//		dst->setCode(who + 1);
//		return true;
//	}
//
//	return false;
//}
//
//#ifdef _USE_CATCAT_S_ALGORITHM
//
//int ChessBoard::decide(const Position &lastestSet, int winCount) {
//	int srcX = lastestSet.x;
//	int srcY = lastestSet.y;
//	int srcOwner = this->getChess(lastestSet)->ownerOrder;
//
//	// 落子左
//	// x: [x, x + winCount)
//	for (int count = 0, i = srcX; i < width && i < srcX + winCount; i++) {
//		if (getChess({i, srcY})->ownerOrder == srcOwner)
//			count++;
//
//		if (count == winCount)
//			return srcOwner;
//	}
//
//	// 落子右
//	// x: (x - winCount, x]
//	for (int count = 0, i = srcX - (winCount - 1); 0 <= i && i <= srcX; i++) {
//		if (getChess({i, srcY})->ownerOrder == srcOwner)
//			count++;
//
//		if (count == winCount)
//			return srcOwner;
//	}
//
//	// 落子上
//	// y: [y, y + winCount)
//	for (int count = 0, i = srcY; i < height && i < srcY + winCount; i++) {
//		if (getChess({srcX, i})->ownerOrder == srcOwner)
//			count++;
//
//		if (count == winCount)
//			return srcOwner;
//	}
//
//	// 落子下
//	// y: (y - winCount, y]
//	for (int count = 0, i = srcY - winCount + 1; 0 <= i && i <= srcY; i++) {
//		if (getChess({srcX, i})->ownerOrder == srcOwner)
//			count++;
//
//		if (count == winCount)
//			return srcOwner;
//	}
//
//	// 落子左上角
//	// x: [x, x + winCount)
//	// y: [y, y + winCount)
//	for (int count = 0, x = srcX, y = srcY; x < width && y < height && x < srcX + winCount && y < srcY + winCount; x++, y++) {
//		if (getChess({x, y})->ownerOrder == srcOwner)
//			count++;
//
//		if (count == winCount)
//			return srcOwner;
//	}
//
//	// 落子右下角
//	// x: (x - winCount, x]
//	// y: (y - winCount, y]
//	for (int count = 0, x = srcX - (winCount - 1), y = srcY - winCount + 1; 0 <= x && 0 <= y && x <= srcX && y <= srcY; x++, y++) {
//		if (getChess({x, y})->ownerOrder == srcOwner)
//			count++;
//
//		if (count == winCount)
//			return srcOwner;
//	}
//
//	// 落子左下角
//	// x: [x, x + winCount)
//	// y: 下 [y, y - winCount) 上
//	for (int count = 0, x = srcX, y = srcY; x < width && 0 <= y && x < srcX + winCount && srcY - winCount + 1 <= y; x++, y--) {
//		if (getChess({x, y})->ownerOrder == srcOwner)
//			count++;
//
//		if (count == winCount)
//			return srcOwner;
//	}
//
//	// 落子右上角
//	// x: (x - winCount, x]
//	// y: 下 (y + winCount, y] 上
//	for (int count = 0, x = srcX - winCount + 1, y = srcY + winCount - 1; 0 <= x && y < height && x <= srcX && srcY <= y; x++, y--) {
//		if (getChess({x, y})->ownerOrder == srcOwner)
//			count++;
//
//		if (count == winCount)
//			return srcOwner;
//	}
//
//	// 平局
//	int count = 0;
//	for (int y = 0; y < height; y++) {
//		for (int x = 0; x < width; x++) {
//			if (getChess({x, y})->ownerOrder != -1)
//				count++;
//		}
//	}
//
//	if (count == width * height) {
//		return -2;
//	}
//
//	// 没有输赢
//	return -1;
//}
//
//#else
//
//int ChessBoard::decide(const Position &lastestSet, int winCount) {
//	int srcX = lastestSet.x;
//	int srcY = lastestSet.y;
//
//	const int srcCode = this->getChess({srcX, srcY})->getOwner();
//	// scanBegin = -(winCount - 1)
//	// 展开为 -winCount + 1
//	const int scanBegin = -winCount + 1;
//	// 获取安全扫描的下标
//	auto getScanIdx = [](int sum)
//			-> int {
//		int i = 0;
//		until(i + sum >= 0)
//				i++;
//		return i + sum;
//	};
//	// 水平
//	for (int count = 0, scanX = getScanIdx(scanBegin + srcX);
//		 scanX < this->width; scanX++)
//		if (srcCode == this->getChess({scanX, srcY})->getOwner()) {
//			count++;
//
//			if (count == winCount)
//				return srcCode;
//		} else
//			count = 0;
//	// 垂直
//	for (int count = 0, scanY = getScanIdx(scanBegin + srcY);
//		 scanY < this->height; scanY++)
//		if (srcCode == this->getChess({srcX, scanY})->getOwner()) {
//			count++;
//
//			if (count == winCount)
//				return srcCode;
//		} else
//			count = 0;
//	// 左上右下
//	for (int count = 0, scan = min(getScanIdx(scanBegin + srcY), getScanIdx(scanBegin + srcX));
//		 scan < this->width && scan < this->height;
//		 scan++)
//		if (srcCode == this->getChess({scan, scan})->getOwner()) {
//			count++;
//
//			if (count == winCount)
//				return srcCode;
//		} else
//			count = 0;
//	//左下右上
//	//之前的getScanIdx在这里不管用
//	int i = 0;
//	until(i - scanBegin + srcY < this->height)
//			i--;
//
//	for (int count = 0,
//			 scanLeft = getScanIdx(scanBegin + srcX),
//			 scanUp = i - scanBegin + srcY;
//		 scanLeft < this->width && scanUp >= 0;
//		 scanLeft++, scanUp--)
//		if (srcCode == this->getChess({scanLeft, scanUp})->getOwner()) {
//			count++;
//			if (count == winCount)
//				return srcCode;
//		} else
//			count = 0;
//
//	for (auto &i : this->chesses)
//		for (auto &j : i) {
//			if (j.getOwner() == 0)
//				return -2;
//		}
//	return -1;
//}
//#endif
//
//void ChessBoard::back(const Position &lastestPos) {
//	//这个back只针对不吃子的棋类
//	OnlySetChess *dst = (OnlySetChess*)this->getChess(lastestPos);
//	dst->setOwner(-1);
//	dst->setCode(0);
//}
